//
// GPSMapEdit
// (c) Konstantin Galichsky (kg@geopainting.com), 2002-2006
//
// 'Postal address items' dialog, 'Countries' page.
//

# include "StdAfx.h"
# include "Resource.h"
# include "PAItems.h"
# include "Map.h"
# include "ChangePAI.h"
# include "HoluxTypes.h"
# include "ListView.h"
# include "EditText.h"
# include "PropertyPages.h"
# include "Globals.h"

struct pa_name_t {
	const char * strTitle;
	string_t * pName;
	string_t * pAbbrevName;
};

static
INT_PTR CALLBACK _EditPANameProc (HWND _hWnd, UINT _uMsg, WPARAM _wParam, LPARAM _lParam) {
	switch (_uMsg) {
		case WM_INITDIALOG: {
			pa_name_t * const pData = reinterpret_cast<pa_name_t *> (_lParam);
			::SetWindowLong (_hWnd, GWL_USERDATA, _lParam);

			// Dialog title.
			::SetWindowText (_hWnd, pData->strTitle);

			// Name.
			if (pData->pName)
				::SetDlgItemText (_hWnd, IDC_NAME, pData->pName->c_str ());

			// Abbreviated name.
			if (pData->pAbbrevName)
				::SetDlgItemText (_hWnd, IDC_ABBREV_NAME, pData->pAbbrevName->c_str ());
			if (g_map.pTypeSet == & g_tsHolux)
				::EnableWindow (::GetDlgItem (_hWnd, IDC_ABBREV_NAME), FALSE);

			::EnableWindow (::GetDlgItem (_hWnd, IDOK), FALSE);

			return TRUE;
		}

		case WM_COMMAND: {
			switch (LOWORD (_wParam)) {
				case IDC_NAME:
				case IDC_ABBREV_NAME: {
					if (HIWORD (_wParam) == EN_CHANGE)
						::EnableWindow (::GetDlgItem (_hWnd, IDOK), TRUE);
					return TRUE;
				}

				case IDOK: {
					pa_name_t * const pData = reinterpret_cast<pa_name_t *> (::GetWindowLong (_hWnd, GWL_USERDATA));

					// Get name.
					const HWND hName = ::GetDlgItem (_hWnd, IDC_NAME);
					const size_t cLen = ::GetWindowTextLength (hName);
					char * const strName = reinterpret_cast<char *> (alloca (cLen + 1));
					::GetWindowText (hName, strName, cLen + 1);

					assert (pData->pName != NULL);
					pData->pName->assign (strName);

					// Get abbreviated name.
					const HWND hAbbrevName = ::GetDlgItem (_hWnd, IDC_ABBREV_NAME);
					const size_t cAbbrevLen = ::GetWindowTextLength (hAbbrevName);
					char * const strAbbrevName = reinterpret_cast<char *> (alloca (cAbbrevLen + 1));
					::GetWindowText (hAbbrevName, strAbbrevName, cAbbrevLen + 1);

					assert (pData->pAbbrevName != NULL);
					pData->pAbbrevName->assign (strAbbrevName);

					::EndDialog (_hWnd, 0);

					return TRUE;
				}

				case IDCANCEL:
					::EndDialog (_hWnd, 1);
					return TRUE;
			}
		}
	}

	return FALSE;
}

bool EditPAName (HWND _hWnd, string_t & _strName, string_t & _strAbbrevName, const char * _strTitle) {
	pa_name_t data = {_strTitle, & _strName, & _strAbbrevName};
	return DlgBox (IDD_EDIT_PA_NAME, _hWnd, _EditPANameProc, reinterpret_cast<LPARAM> (& data)) == 0;
}

///////////////////////////////////////////////////////////////

void InitCountriesList (CListView & _List) {
	AddColumn (_List, 0, "Country");
	AddColumn (_List, 1, "Code");

	_List.SetExtStyle (LVS_EX_FULLROWSELECT);
}

void FillCountriesList (CListView & _List, const country_t * _pSelectCountry) {
	ListView_DeleteAllItems (_List);

	CCritSec::CLock lock (g_cs);

	size_t cItem = 0;
	for (countries_t::iterator i = g_map.Countries.begin (); i != g_map.Countries.end (); ++ i) {
		const country_t & country = * i;
		if (country.IsDeleted ())
			continue;

		InsertItem     (_List, cItem, reinterpret_cast<LPARAM> (& country), "%s", OutputPAString (country.strName));
		SetSubItemText (_List, cItem, 1, "%s", OutputPAString (country.strAbbrevName));

		if (& country == _pSelectCountry)
			SetSelection (_List, cItem);

		++ cItem;
	}

	// Set the best width.
	AutoSizeColumns (_List);

	_List.Sort ();
}

///////////////////////////////////////////////////////////////

CCountriesPage::CCountriesPage () : CPropertyPages::CPage (IDD_PA_COUNTRIES) {}

void CCountriesPage::_UpdateTotalCountries () {
	size_t cCountries = 0;
	for (countries_t::iterator i = g_map.Countries.begin (); i != g_map.Countries.end (); ++ i) {
		const country_t & country = * i;
		if (country.IsDeleted ())
			continue;

		++ cCountries;
	}

	char strTotal [32];
	::sprintf (strTotal, "Total: %d", cCountries);

	SetDlgItemText (IDC_TOTAL, strTotal);
}

bool CCountriesPage::OnInit (HWND _hwndFocus) {
	// Buttons.
	EnableDlgItem (IDC_REMOVE, false);
	EnableDlgItem (IDC_RENAME, false);

	// Countries.
	m_List.Init (m_hWnd, IDC_LIST, "Countries");
	InitCountriesList (m_List);

	return true;
}

void CCountriesPage::OnDestroy () {
	m_List.Destroy ();
}

void CCountriesPage::OnCommand (WORD _wCmd, WORD _wNotifyCode, HWND _hwndCtl) {
	switch (_wCmd) {
		case IDC_ADD: {
			string_t strName, strAbbrevName;
			if (EditPAName (m_hWnd, strName, strAbbrevName, "Add country")) {
				// Create new country.
				AddCountry (strName, strAbbrevName);

				FillCountriesList (m_List, & g_map.Countries.back ());
				_UpdateTotalCountries ();
			}
			return;
		}

		case IDC_RENAME: {
			const size_t cSel = ListView_GetSelectionMark (m_List);
			if (cSel == -1)
				break;

			country_t * const pCountry = reinterpret_cast<country_t *> (GetLParam (m_List, cSel));

			string_t strName       = pCountry->strName;
			string_t strAbbrevName = pCountry->strAbbrevName;
			if (EditPAName (m_hWnd, strName, strAbbrevName, "Rename country")) {
				RenamePAI (pCountry, strName, strAbbrevName);

				SetItemText    (m_List, cSel, strName.c_str ());
				SetSubItemText (m_List, cSel, 1, "%s", strAbbrevName.c_str ());
			}

			return;
		}

		case IDC_REMOVE: {
			EnableDlgItem (IDC_RENAME, false);
			EnableDlgItem (IDC_REMOVE, false);

			const size_t cSel = ListView_GetSelectionMark (m_List);
			if (cSel == -1)
				break;

			country_t * const pCountry = reinterpret_cast<country_t *> (GetLParam (m_List, cSel));
			DeletePAI (pCountry);

			FillCountriesList (m_List);
			_UpdateTotalCountries ();

			return;
		}
	}
}

bool CCountriesPage::OnNotify (int _idCtrl, NMHDR * _pInfo) {
	switch (_pInfo->code) {
		case NM_RCLICK:
			m_List.PopupMenu_OnHeaderRClick (_pInfo);
			return false;

		case LVN_COLUMNCLICK:
			m_List.Sort_OnColumnClick (_pInfo);
			break;

		case PSN_SETACTIVE: {
			const size_t cSel = ListView_GetSelectionMark (m_List);
			country_t * const pCountry = cSel == -1 ? NULL : reinterpret_cast<country_t *> (GetLParam (m_List, cSel));
			FillCountriesList (m_List, pCountry);
			_UpdateTotalCountries ();
		}
		case NM_CLICK:
		case LVN_KEYDOWN: {
			const size_t cSel = ListView_GetSelectionMark (m_List);
			EnableDlgItem (IDC_RENAME, cSel != -1);
			EnableDlgItem (IDC_REMOVE, cSel != -1);
			break;
		}
	}

	return CPage::OnNotify (_idCtrl, _pInfo);
}
